package com.geekai.chat.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import com.geekai.chat.config.AiConfig;
import com.geekai.chat.dto.ChatRequest;
import com.geekai.chat.dto.ChatResponse;
import com.geekai.chat.entity.Conversation;
import com.geekai.chat.entity.Message;
import com.geekai.chat.service.AiChatService;
import com.geekai.chat.service.AiModelFactory;
import com.geekai.chat.service.ConversationService;
import com.geekai.chat.service.MessageService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class AiChatServiceImpl implements AiChatService {

    private final ConversationService conversationService;
    private final MessageService messageService;
    private final AiModelFactory aiModelFactory;

    @Override
    public ChatResponse chat(ChatRequest chatRequest, String username) {
        // 验证对话权限
        Conversation conversation = conversationService.getById(chatRequest.getConversationId());
        if (conversation == null) {
            throw new RuntimeException("对话不存在");
        }

        // 保存用户消息
        Message userMessage = messageService.saveUserMessage(
                chatRequest.getConversationId(),
                chatRequest.getContent()
        );

        try {
            // 获取模型类型，默认为 gpt
            String modelType = chatRequest.getModelType() != null ? chatRequest.getModelType() : "gpt";
            
            // 构建消息历史
            List<Message> recentMessages = messageService.getRecentMessages(
                    chatRequest.getConversationId(), 10
            );
            List<Map<String, String>> messages = buildMessageHistory(recentMessages, chatRequest.getContent());

            // 调用AI API
            String aiResponse = callAiApi(messages, modelType);

            // 保存AI回复
            Message assistantMessage = messageService.saveAssistantMessage(
                    chatRequest.getConversationId(),
                    aiResponse,
                    modelType,
                    calculateTokens(aiResponse)
            );

            // 检查是否是第一次对话，如果是则更新标题
            updateConversationTitleIfNeeded(conversation, chatRequest.getContent(), aiResponse, username);

            // 构建响应
            ChatResponse chatResponse = new ChatResponse();
            chatResponse.setMessageId(assistantMessage.getId());
            chatResponse.setContent(aiResponse);
            chatResponse.setRole(Message.Role.ASSISTANT.getValue());
            chatResponse.setTokens(assistantMessage.getTokens());
            chatResponse.setModel(assistantMessage.getModel());

            return chatResponse;

        } catch (Exception e) {
            log.error("AI chat error: ", e);
            throw new RuntimeException("AI服务暂时不可用，请稍后重试: " + e.getMessage());
        }
    }

    @Override
    public SseEmitter streamChat(ChatRequest chatRequest, String username) {
        SseEmitter emitter = new SseEmitter(30000L);

        // 验证对话权限
        Conversation conversation = conversationService.getById(chatRequest.getConversationId());
        if (conversation == null) {
            emitter.completeWithError(new RuntimeException("对话不存在"));
            return emitter;
        }

        // 保存用户消息
        messageService.saveUserMessage(chatRequest.getConversationId(), chatRequest.getContent());

        // 异步处理流式响应
        new Thread(() -> {
            try {
                // 获取模型类型，默认为 gpt
                String modelType = chatRequest.getModelType() != null ? chatRequest.getModelType() : "gpt";
                
                // 构建消息历史
                List<Message> recentMessages = messageService.getRecentMessages(
                        chatRequest.getConversationId(), 10
                );
                List<Map<String, String>> messages = buildMessageHistory(recentMessages, chatRequest.getContent());

                // 调用AI API
                String fullResponse = callAiApi(messages, modelType);

                // 模拟流式响应
                simulateStreamResponse(emitter, fullResponse);

                // 保存完整回复
                messageService.saveAssistantMessage(
                        chatRequest.getConversationId(),
                        fullResponse,
                        modelType,
                        calculateTokens(fullResponse)
                );

                // 检查是否是第一次对话，如果是则更新标题
                updateConversationTitleIfNeeded(conversation, chatRequest.getContent(), fullResponse, username);

                emitter.complete();

            } catch (Exception e) {
                log.error("Stream chat error: ", e);
                emitter.completeWithError(e);
            }
        }).start();

        return emitter;
    }

    @Override
    public String generateTitle(String content) {
        try {
            List<Map<String, String>> messages = new ArrayList<>();
            Map<String, String> systemMessage = new HashMap<>();
            systemMessage.put("role", "system");
            systemMessage.put("content", "根据用户的消息内容生成一个简短的对话标题，不超过10个字。标题应该简洁明了，能够概括对话的主要内容。");
            messages.add(systemMessage);

            Map<String, String> userMessage = new HashMap<>();
            userMessage.put("role", "user");
            userMessage.put("content", content);
            messages.add(userMessage);

            return callAiApi(messages, "gpt");
        } catch (Exception e) {
            log.error("Generate title error: ", e);
            return "新对话";
        }
    }

    /**
     * 基于用户消息和AI回复生成对话标题
     */
    private String generateTitleFromConversation(String userMessage, String aiResponse) {
        try {
            List<Map<String, String>> messages = new ArrayList<>();
            Map<String, String> systemMessage = new HashMap<>();
            systemMessage.put("role", "system");
            systemMessage.put("content", "根据用户的问题和AI的回答，生成一个简洁的对话标题，不超过10个字。标题应该准确概括对话的核心内容。");
            messages.add(systemMessage);

            Map<String, String> userMessageMap = new HashMap<>();
            userMessageMap.put("role", "user");
            userMessageMap.put("content", "用户问题：" + userMessage + "\nAI回答：" + aiResponse + "\n请生成一个合适的对话标题。");
            messages.add(userMessageMap);

            return callAiApi(messages, "gpt");
        } catch (Exception e) {
            log.error("Generate title from conversation error: ", e);
            // 如果AI生成标题失败，则使用用户消息的前几个字作为标题
            return generateSimpleTitle(userMessage);
        }
    }

    /**
     * 生成简单标题作为后备方案
     */
    private String generateSimpleTitle(String userMessage) {
        if (userMessage == null || userMessage.trim().isEmpty()) {
            return "新对话";
        }
        
        String trimmedMessage = userMessage.trim();
        if (trimmedMessage.length() <= 10) {
            return trimmedMessage;
        }
        
        // 取前10个字符，并确保不截断中文字符
        String title = trimmedMessage.substring(0, Math.min(10, trimmedMessage.length()));
        // 如果截断后以中文字符结尾，去掉最后一个字符避免显示不完整
        if (title.length() > 0 && title.charAt(title.length() - 1) > 127) {
            title = title.substring(0, title.length() - 1);
        }
        return title + "...";
    }

    private List<Map<String, String>> buildMessageHistory(List<Message> recentMessages, String currentContent) {
        List<Map<String, String>> messages = new ArrayList<>();

        // 添加系统消息
        Map<String, String> systemMessage = new HashMap<>();
        systemMessage.put("role", "system");
        systemMessage.put("content", "你是一个有用的AI助手。请用中文回答用户的问题。");
        messages.add(systemMessage);

        // 添加历史消息
        for (Message message : recentMessages) {
            Map<String, String> msg = new HashMap<>();
            msg.put("role", message.getRole());
            msg.put("content", message.getContent());
            messages.add(msg);
        }

        // 添加当前消息
        Map<String, String> currentMessage = new HashMap<>();
        currentMessage.put("role", "user");
        currentMessage.put("content", currentContent);
        messages.add(currentMessage);

        return messages;
    }


    private String callAiApi(List<Map<String, String>> messages, String modelType) {
        try {
            AiConfig.ModelConfig config = aiModelFactory.getModelConfig(modelType);
            
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", config.getModelName());
            requestBody.put("messages", messages);
            requestBody.put("temperature", config.getTemperature());
            requestBody.put("max_tokens", config.getMaxTokens());
            
            // 所有模型都使用OpenAI兼容的API格式
            return callOpenAiCompatibleApi(config, requestBody);
        } catch (Exception e) {
            log.error("AI API call error: ", e);
            // 直接抛出异常，不再返回模拟响应
            throw new RuntimeException("AI服务调用失败: " + e.getMessage(), e);
        }
    }
    
    private String callOpenAiCompatibleApi(AiConfig.ModelConfig config, Map<String, Object> requestBody) {
        WebClient webClient = aiModelFactory.getWebClientBuilder()
                .baseUrl(config.getBaseUrl())
                .build();
        
        return webClient.post()
                .uri("/chat/completions")
                .header("Authorization", "Bearer " + config.getApiKey())
                .header("Content-Type", "application/json")
                .bodyValue(requestBody)
                .retrieve()
                .bodyToMono(Map.class)
                .map(response -> {
                  log.info("AI API响应: " + response);
                    List<Map<String, Object>> choices = (List<Map<String, Object>>) response.get("choices");
                    if (choices != null && !choices.isEmpty()) {
                        Map<String, Object> choice = choices.get(0);
                        Map<String, Object> message = (Map<String, Object>) choice.get("message");
                        if (message != null && message.get("content") != null) {
                            return (String) message.get("content");
                        }
                    }
                    // 如果响应格式不正确，抛出异常
                    throw new RuntimeException("AI API响应格式错误: " + response);
                })
                .block();
    }

    private void simulateStreamResponse(SseEmitter emitter, String fullResponse) throws IOException {
        // 使用更智能的分割方式，保留换行符和Markdown格式
        String[] chunks = splitResponseIntoSensibleChunks(fullResponse);
        
        for (int i = 0; i < chunks.length; i++) {
            try {
                Thread.sleep(30); // 减少延迟，提升响应速度
                
                String data = String.format("{\"content\":\"%s\",\"finished\":%s}", 
                    escapeJsonString(chunks[i]), i == chunks.length - 1);
                
                // 发送标准的 SSE 格式数据
                emitter.send(SseEmitter.event()
                        .data(data));
                        
            } catch (Exception e) {
                log.error("Stream send error: ", e);
                break;
            }
        }
    }
    
    /**
     * 将响应分割成有意义的块，保留换行符和Markdown格式
     */
    private String[] splitResponseIntoSensibleChunks(String response) {
        if (response == null || response.isEmpty()) {
            return new String[]{""};
        }
        
        // 按行分割，保留换行符
        String[] lines = response.split("(?<=\\n)", -1);
        List<String> chunks = new ArrayList<>();
        
        for (String line : lines) {
            if (line.trim().isEmpty()) {
                // 空行单独作为一个块
                chunks.add(line);
            } else if (line.startsWith("```") || line.startsWith("`") || line.startsWith("#") || line.startsWith("- ")) {
                // Markdown特殊格式单独作为一个块
                chunks.add(line);
            } else if (line.length() > 50) {
                // 长行按句子分割
                String[] sentences = line.split("(?<=[.!?。！？])\\s*", -1);
                for (String sentence : sentences) {
                    if (!sentence.trim().isEmpty()) {
                        chunks.add(sentence + " ");
                    }
                }
            } else {
                // 短行直接添加
                chunks.add(line);
            }
        }
        
        return chunks.toArray(new String[0]);
    }
    
    /**
     * 转义JSON字符串中的特殊字符
     */
    private String escapeJsonString(String input) {
        if (input == null) {
            return "";
        }
        
        return input.replace("\\", "\\\\")
                   .replace("\"", "\\\"")
                   .replace("\n", "\\n")
                   .replace("\r", "\\r")
                   .replace("\t", "\\t");
    }

    private Integer calculateTokens(String content) {
        // 简单的token计算，实际项目中应该使用更准确的方法
        return content.length() / 4;
    }

    private void updateConversationTitleIfNeeded(Conversation conversation, String userMessageContent, String aiResponseContent, String username) {
        try {
            // 检查是否是第一次对话（标题为默认值）
            if (conversation.getTitle() == null || conversation.getTitle().equals("新对话") || conversation.getTitle().trim().isEmpty()) {
                // 使用更智能的标题生成方法
                String newTitle = generateTitleFromConversation(userMessageContent, aiResponseContent);
                
                // 验证生成的标题是否有效
                if (newTitle != null && !newTitle.trim().isEmpty() && !newTitle.equals("新对话")) {
                    // 更新对话标题
                    conversation.setTitle(newTitle);
                    conversationService.updateById(conversation);
                    log.info("Conversation title updated for user: {}, conversationId: {}, newTitle: {}", 
                            username, conversation.getId(), newTitle);
                } else {
                    log.warn("Generated title is invalid for conversation: {}, title: {}", 
                            conversation.getId(), newTitle);
                }
            }
        } catch (Exception e) {
            log.error("Failed to update conversation title for conversation: {}, user: {}", 
                    conversation.getId(), username, e);
            // 标题更新失败不影响主要对话流程
        }
    }
}